﻿using BonjourQuotation.DataAccess.Entity_Framework;
using BonjourQuotation.ObjectModel.AccountData;
using BonjourQuotation.ObjectModel.BusinessData;
using BonjourQuotation.ObjectModel.ErrorData;
using BonjourQuotation.ObjectModel.LoggerData;
using BonjourQuotation.ObjectModel.CustomerData;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BonjourQuotation.DataAccess.Repositories
{
    public class CustomerRepository : ICustomerRepository
    {
        private readonly BonDataEntities _context = new BonDataEntities();
        private readonly log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        public ErrorBInfo CreateCustomer(CustomerDetailsBData CustomerData)
        {
            ErrorBInfo Error = new ErrorBInfo();
            try
            {
                tblCustomer NewCustomer = new tblCustomer()
                {
                    CustomerCode = CustomerData.CustomerCode,
                    OrganizationName = CustomerData.OrganizationName,
                    Address = CustomerData.Address,
                    Address2 = CustomerData.Address2,
                    City = (from city in _context.tblCities where city.CityID == CustomerData.CityID select city.City).SingleOrDefault(),
                    CityID = CustomerData.CityID,
                    StateID = CustomerData.SelectedStateID,
                    CountryID = CustomerData.SelectedCountryID,
                    PostalCode = CustomerData.PostalCode,
                    CCEMail = CustomerData.CCEMail,
                    PhoneNumber1 = CustomerData.PhoneNumber1,
                    PhoneNumber2 = CustomerData.PhoneNumber2,
                    FaxNumber = CustomerData.FaxNumber,
                    Note = CustomerData.Note,
                    Mail = CustomerData.Mail,
                    Active = CustomerData.Active,
                };
                _context.tblCustomers.Add(NewCustomer);
                _context.SaveChanges();
            }
            catch (Exception ex)
            {
                Error.errorCode = 100;
                Error.Message = ex.Message;
                logger.Error(ex.ToMessageAndCompleteStacktrace());
            }
            return Error;
        }
        public ManageCustomersGridBData LoadCustomers(int PageNumber)
        {
            ManageCustomersGridBData Customers = new ManageCustomersGridBData();
            Customers.Rows = new List<ManageCustomersGridRowBData>();
            Customers.Rows = (from customer in _context.tblCustomers
                              orderby customer.OrganizationName
                              select new ManageCustomersGridRowBData()
                              {
                                  CustomerID = customer.CustomerID,
                                  OrganizationName = customer.OrganizationName,
                                  CustomerCode = customer.CustomerCode,
                                  City = customer.City,
                                  Active = customer.Active,
                              }).Take(PageNumber * ManageCustomersGridBData.PageCount).ToList();

            Customers.City = (from city in _context.tblCities
                              where city.Active == true
                              orderby city.City
                              select new
                              {
                                  Key = city.CityID,
                                  Value = city.City
                              }).ToDictionary(o => o.Key, o => o.Value);
            Customers.Active = new Dictionary<bool, string>
            {
                {true,"Yes"},
                {false,"No"},
            };
            return Customers;
        }
        public ManageCustomersGridBData LoadCustomerByID(int CustomerID)
        {
            ManageCustomersGridBData Customers = new ManageCustomersGridBData();
            Customers.Rows = new List<ManageCustomersGridRowBData>();
            Customers.Rows = (from customer in _context.tblCustomers
                              where customer.CustomerID == CustomerID
                              orderby customer.OrganizationName
                              select new ManageCustomersGridRowBData()
                              {
                                  CustomerID = customer.CustomerID,
                                  OrganizationName = customer.OrganizationName,
                                  CustomerCode = customer.CustomerCode,
                                  City = customer.City,
                                  Active = customer.Active,
                              }).ToList();

            Customers.City = (from city in _context.tblCities
                              where city.Active == true
                              orderby city.City
                              select new
                              {
                                  Key = city.CityID,
                                  Value = city.City
                              }).ToDictionary(o => o.Key, o => o.Value);
            Customers.Active = new Dictionary<bool, string>
            {
                {true,"Yes"},
                {false,"No"},
            };
            return Customers;
        }
        public ManageCustomersGridBData LoadSearchedCustomers(ManageCustomersGridBData Data)
        {
            var FilterCustomer = _context.tblCustomers.AsQueryable();
            if (Data.OrganizationName != null && Data.OrganizationName.Length > 0)
                FilterCustomer = FilterCustomer.Where(cust => cust.OrganizationName.Contains(Data.OrganizationName.Trim()));
            if (Data.CustomerCode != null && Data.CustomerCode.Length > 0)
                FilterCustomer = FilterCustomer.Where(cust => cust.CustomerCode.Contains(Data.CustomerCode.Trim()));
            if (Data.SelectedCity != null)
                FilterCustomer = FilterCustomer.Where(cust => cust.City == Data.SelectedCity);
            if (Data.SelectedActive != null)
                FilterCustomer = FilterCustomer.Where(cust => cust.Active == Data.SelectedActive);
            ManageCustomersGridBData AllCustomers;
            AllCustomers = new ManageCustomersGridBData();
            AllCustomers.Rows = new List<ManageCustomersGridRowBData>();
            AllCustomers.Rows = (from customer in FilterCustomer
                                 orderby customer.OrganizationName
                                 select new ManageCustomersGridRowBData()
                                 {
                                     CustomerID = customer.CustomerID,
                                     OrganizationName = customer.OrganizationName,
                                     CustomerCode = customer.CustomerCode,
                                     City = customer.City,
                                     Active = customer.Active,
                                 }).Take(Data.PageNum * ManageCustomersGridBData.PageCount).ToList();
           
            AllCustomers.City = (from city in _context.tblCities
                                 where city.Active == true
                                 orderby city.City
                                 select new
                                 {
                                     Key = city.CityID,
                                     Value = city.City
                                 }).ToDictionary(o => o.Key, o => o.Value);
            return AllCustomers;
        }
        public CustomerDetailsBData LoadCustomerDetailsByID(int CustomerID)
        {
            CustomerDetailsBData CustomerData = null;
            if (CustomerID == 0)
            {
                CustomerData = new CustomerDetailsBData();
                CustomerData.StateID = new Dictionary<string, string>();
                CustomerData.City = new Dictionary<int, string>();
                CustomerData.ContactRows = new List<CustomerContactDetailsBData>();
            }
            else
            {
                if (CustomerID == -1)
                {
                    CustomerID = _context.tblCustomers.Max(cust => cust.CustomerID);
                }
                CustomerData = (from Cust in _context.tblCustomers
                                where Cust.CustomerID == CustomerID
                                select new CustomerDetailsBData
                                {
                                    CustomerID = Cust.CustomerID,
                                    CustomerCode = Cust.CustomerCode,
                                    OrganizationName = Cust.OrganizationName,
                                    Address = Cust.Address,
                                    Address2 = Cust.Address2,
                                    SelectedCity = Cust.City,
                                    SelectedStateID = Cust.StateID,
                                    SelectedCountryID = Cust.CountryID,
                                    PostalCode = Cust.PostalCode,
                                    CCEMail = Cust.CCEMail,
                                    PhoneNumber1 = Cust.PhoneNumber1,
                                    PhoneNumber2 = Cust.PhoneNumber2,
                                    FaxNumber = Cust.FaxNumber,
                                    Note = Cust.Note,
                                    Mail = Cust.Mail,
                                    Active = Cust.Active,
                                }).SingleOrDefault();

                CustomerData.ContactRows = new List<CustomerContactDetailsBData>();
                CustomerData.ContactRows = (from CustCont in _context.tblCustomerContacts
                                            where CustCont.CustomerID == CustomerID
                                            select new CustomerContactDetailsBData
                                            {
                                                CCID = CustCont.CCID,
                                                CustomerID = CustCont.CustomerID,
                                                Name = CustCont.Name,
                                                Title = CustCont.Title,
                                                EMail = CustCont.EMail,
                                                Phone = CustCont.Phone,
                                                Fax = CustCont.Fax,
                                            }).ToList();
                if (CustomerData.SelectedCountryID == 1)
                {
                    CustomerData.StateID = (from state in _context.tblStates where state.Active == true orderby state.StateID select new { Key = state.StateID, Value = state.StateID }).ToDictionary(o => o.Key, o => o.Value);
                    if (CustomerData.SelectedStateID == null)
                    {
                        CustomerData.City = new Dictionary<int, string>();
                    }
                    else
                    {
                        CustomerData.City = (from city in _context.tblCities where city.StateID == CustomerData.SelectedStateID && city.Active == true orderby city.City select new { Key = city.CityID, Value = city.City }).ToDictionary(o => o.Key, o => o.Value);
                        if (CustomerData.City == null)
                            CustomerData.City = new Dictionary<int, string>();
                        if (CustomerData.CityID == null && CustomerData.SelectedCity != null && CustomerData.SelectedCity != "")
                        {
                            CustomerData.City.Add(-1, CustomerData.SelectedCity);
                            CustomerData.CityID = -1;
                        }
                    }
                }
                else
                {
                    CustomerData.StateID = new Dictionary<string, string>();
                    if (CustomerData.SelectedCountryID == null)
                        CustomerData.City = new Dictionary<int, string>();
                    else
                    {
                        CustomerData.City = (from city in _context.tblCities where city.CountryID == CustomerData.SelectedCountryID && city.Active == true orderby city.City select new { Key = city.CityID, Value = city.City }).ToDictionary(o => o.Key, o => o.Value);
                        if (CustomerData.City == null)
                            CustomerData.City = new Dictionary<int, string>();
                        if (CustomerData.CityID == null && CustomerData.SelectedCity != null && CustomerData.SelectedCity != "")
                        {
                            CustomerData.City.Add(-1, CustomerData.SelectedCity);
                            CustomerData.CityID = -1;
                        }
                    }
                }
            }
            CustomerData.CountryID = (from cnt in _context.tblCountries where cnt.Active == true orderby cnt.CountryName select new { Key = cnt.CountryID, Value = cnt.CountryName }).ToDictionary(o => o.Key, o => o.Value);
            return CustomerData;
        }
        public CustomerGroupsBData LoadCustomerGroupsByID(int CustomerID)
        {
            CustomerGroupsBData CustomerGroupsData = new CustomerGroupsBData();
            CustomerGroupsData.Rows = new List<CustomerGroupsRowBData>();
            CustomerGroupsData.Rows = (from GroupStatus in _context.tblGroupStatus
                                       from Group in _context.tblGroups
                                       where Group.CustomerID == CustomerID
                                       && Group.StatusID == GroupStatus.StatusID
                                       select new CustomerGroupsRowBData
                                       {
                                             GroupID = Group.GroupID,
                                             ArrivalDate = Group.ArrivalDate,
                                             DepartureDate = Group.DepartureDate,
                                             GroupCode = Group.GroupCode,
                                             GroupName = Group.GroupName,
                                             GroupStatusDesc = GroupStatus.StatusDesc,
                                             Pax = Group.NoOfPerson,
                                             Rooms = Group.Rooms,
                                             IsGir = Group.IsGir,
                                       }).ToList();
            var GirCustRows = (from GroupStatus in _context.tblGroupStatus
                               from Group in _context.tblGroups
                               from GroupDet in _context.tblGirGroupDetails
                               where GroupDet.CustomerID == CustomerID
                               && GroupDet.GroupID == Group.GroupID
                               && Group.StatusID == GroupStatus.StatusID
                               select new CustomerGroupsRowBData
                               {
                                   GroupID = Group.GroupID,
                                   ArrivalDate = Group.ArrivalDate,
                                   DepartureDate = Group.DepartureDate,
                                   GroupCode = Group.GroupCode,
                                   GroupName = Group.GroupName,
                                   GroupStatusDesc = GroupStatus.StatusDesc,
                                   Pax = Group.NoOfPerson,
                                   Rooms = Group.Rooms,
                                   IsGir = Group.IsGir,
                               }).ToList();
            CustomerGroupsData.Rows.AddRange(GirCustRows);
            CustomerGroupsData.GroupStatus = (from gstatus in _context.tblGroupStatus
                                              select new
                                              {
                                                  Key = gstatus.StatusID,
                                                  Value = gstatus.StatusDesc,
                                              }).ToDictionary(o => o.Key, o => o.Value);
            return CustomerGroupsData;
        }
        public CustomerQuotationsBData LoadCustomerQuotationsByID(int CustomerID)
        {
            CustomerQuotationsBData CustomerQuotaData = new CustomerQuotationsBData();
            CustomerQuotaData.Rows = new List<CustomerQuotationsRowBData>();
            CustomerQuotaData.Rows = (from Quota in _context.tblQuotations
                                      where Quota.CustomerID == CustomerID
                                      && Quota.Active == true
                                      select new CustomerQuotationsRowBData
                                       {
                                           QuotaID = Quota.QuotaID,
                                           ArrivalDate = Quota.ArrivalDate,
                                           DepartureDate = Quota.DepartureDate,
                                           QuotaCode = Quota.QuotaCode,
                                           QuotaName = Quota.QuotaName,
                                           Nights = Quota.NoOfNights,
                                           Meals = Quota.NoOfMeals,
                                           Accepted = Quota.Accepted,
                                       }).ToList();
            return CustomerQuotaData;
        }
        public CustomerInvoicesBData LoadCustomerInvoicesByID(int CustomerID)
        {
            CustomerInvoicesBData CustomerInvoicesData = new CustomerInvoicesBData();
            CustomerInvoicesData.Rows = new List<CustomerInvoicesRowBData>();
            var GirGroupIDs = _context.tblGirGroupDetails.Where(GirDet => GirDet.CustomerID == CustomerID).Select(GirDet => GirDet.GroupID).ToList();
            CustomerInvoicesData.Rows = (from Groups in _context.tblGroups
                                         where Groups.CustomerID == CustomerID
                                         || GirGroupIDs.Contains(Groups.GroupID)
                                         //&& Groups.Cancelled == false
                                         orderby Groups.FinalPayment
                                         select new CustomerInvoicesRowBData
                                         {
                                              CustomerID = CustomerID,
                                              GroupID = Groups.GroupID,
                                              FinalPayment = Groups.FinalPayment,
                                              GroupCode = Groups.GroupCode,
                                              GroupName = Groups.GroupName,
                                              IsGir = Groups.IsGir,
                                              IsPushed = Groups.IsPushed,
                                              Payed = (from Deposits in _context.tblDeposits
                                                       where Groups.GroupID == Deposits.GroupID
                                                       && Deposits.Received !=null
                                                       select Deposits.Received).Sum(),
                                              Charged = Groups.IsGir == true 
                                                       ? (from GirGroupInvoice in _context.tblGirGroupInvoices
                                                         where Groups.GroupID == GirGroupInvoice.GroupID
                                                         && GirGroupInvoice.Debit != null
                                                         && GirGroupInvoice.Credit != null
                                                         select (GirGroupInvoice.Debit - GirGroupInvoice.Credit)).Sum()
                                                       : (from GroupInvoice in _context.tblGroupInvoices
                                                         where Groups.GroupID == GroupInvoice.GroupID
                                                         && GroupInvoice.Debit != null
                                                         && GroupInvoice.Credit != null
                                                         select (GroupInvoice.Debit - GroupInvoice.Credit)).Sum(),
                                              Balance = (from deposits in _context.tblDeposits
                                                         where Groups.GroupID == deposits.GroupID
                                                         && deposits.Received != null
                                                         select deposits.Received).Sum() != null ?
                                                         (from deposits in _context.tblDeposits
                                                         where Groups.GroupID == deposits.GroupID
                                                         && deposits.Received != null
                                                         select deposits.Received).Sum() : 0
                                                         +
                                                        (Groups.IsGir == true 
                                                        ? (from GroupInvoice in _context.tblGroupInvoices
                                                           where Groups.GroupID == GroupInvoice.GroupID
                                                           && GroupInvoice.Debit != null
                                                           && GroupInvoice.Credit != null
                                                           select (GroupInvoice.Credit - GroupInvoice.Debit)).Sum() != null ?
                                                           (from GroupInvoice in _context.tblGroupInvoices
                                                           where Groups.GroupID == GroupInvoice.GroupID
                                                           && GroupInvoice.Debit != null
                                                           && GroupInvoice.Credit != null
                                                           select (GroupInvoice.Credit - GroupInvoice.Debit)).Sum():0
                                                        : (from GirGroupInvoice in _context.tblGirGroupInvoices
                                                           where Groups.GroupID == GirGroupInvoice.GroupID
                                                           && GirGroupInvoice.Debit != null
                                                           && GirGroupInvoice.Credit != null
                                                           select (GirGroupInvoice.Credit - GirGroupInvoice.Debit)).Sum() != null ?
                                                           (from GirGroupInvoice in _context.tblGirGroupInvoices
                                                            where Groups.GroupID == GirGroupInvoice.GroupID
                                                            && GirGroupInvoice.Debit != null
                                                            && GirGroupInvoice.Credit != null
                                                            select (GirGroupInvoice.Credit - GirGroupInvoice.Debit)).Sum() : 0),
                                         }).ToList();
            return CustomerInvoicesData;
        }
        public CustomerPaymentsBData LoadCustomerPaymentsByID(int CustomerID)
        {
            CustomerPaymentsBData CustomerPaymentsData = new CustomerPaymentsBData();
            CustomerPaymentsData.Rows = new List<CustomerPaymentsRowBData>();
            CustomerPaymentsData.Rows = (from Payment in _context.tblPayments
                                         where Payment.CustomerID == CustomerID
                                         orderby Payment.LineNo
                                         select new CustomerPaymentsRowBData
                                         {
                                             LineNo = Payment.LineNo,
                                             PayTypeID = Payment.PayTypeID,
                                             PaymentDate = Payment.PaymentDate,
                                             RefundF = Payment.RefundF,
                                             Description = Payment.Description,
                                             Debit = Payment.Debit,
                                             Credit = Payment.Credit,
                                         }).ToList();
            CustomerPaymentsData.PaymentTypes = (from PaymentType in _context.tblPayTypes
                                                 where PaymentType.Active == true
                                                 select new
                                                 {
                                                     Key = PaymentType.PayTypeID,
                                                     Value = PaymentType.PayTypeCode + PaymentType.PayTypeDesc,
                                                 }).ToDictionary(o => o.Key, o => o.Value);
            CustomerPaymentsData.CustomerID = CustomerID;
            return CustomerPaymentsData;
        }
        public CustomerPaymentGroupsBData LoadCustomerPaymentGroupsByID(int CustomerID , int? LineNo)
        {
            CustomerPaymentGroupsBData CustomerPaymentGroupsData = new CustomerPaymentGroupsBData();
            CustomerPaymentGroupsData.Rows = new List<CustomerPaymentGroupsRowBData>();
            CustomerPaymentGroupsData.Rows = (from Deposit in _context.tblDeposits
                                              where Deposit.CustomerID == CustomerID
                                              && Deposit.LineNo == LineNo
                                              orderby Deposit.LineNo
                                              select new CustomerPaymentGroupsRowBData
                                              {
                                                  SelectedGroupsID = Deposit.GroupID,
                                                  OldSelectedGroupsID = Deposit.GroupID,
                                                  Refunded = Deposit.Refunded,
                                                  Received = Deposit.Received,
                                              }).ToList();
            CustomerPaymentGroupsData.CustomerID = CustomerID;
            CustomerPaymentGroupsData.LineNo = LineNo;
            var GirGroupIDs = _context.tblGirGroupDetails.Where(GirDet => GirDet.CustomerID == CustomerID).Select(GirDet => GirDet.GroupID).ToList();
            CustomerPaymentGroupsData.Groups = (from Groups in _context.tblGroups
                                                where Groups.CustomerID==CustomerID
                                                || GirGroupIDs.Contains(Groups.GroupID)
                                                select new
                                                {
                                                    Key = Groups.GroupID,
                                                    Value = Groups.GroupCode + " - " + Groups.GroupName,
                                                }).ToDictionary(o => o.Key, o => o.Value);
            return CustomerPaymentGroupsData;
        }
        public CustomerGroupsBData LoadCustomerSearchedGroupsByID(int CustomerID, int CustomerStatusID)
        {
            CustomerGroupsBData CustomerGroupsData = new CustomerGroupsBData();
            CustomerGroupsData.Rows = new List<CustomerGroupsRowBData>();
            CustomerGroupsData.Rows = (from GroupStatus in _context.tblGroupStatus
                                       from Group in _context.tblGroups
                                       where Group.CustomerID == CustomerID
                                       && Group.StatusID == CustomerStatusID
                                       && Group.StatusID == GroupStatus.StatusID
                                       select new CustomerGroupsRowBData
                                       {
                                           GroupID = Group.GroupID,
                                           ArrivalDate = Group.ArrivalDate,
                                           DepartureDate = Group.DepartureDate,
                                           GroupCode = Group.GroupCode,
                                           GroupName = Group.GroupName,
                                           GroupStatusDesc = GroupStatus.StatusDesc,
                                           Pax = Group.NoOfPerson,
                                           Rooms = Group.Rooms,
                                       }).ToList();
            CustomerGroupsData.GroupStatus = (from gstatus in _context.tblGroupStatus
                                              select new
                                              {
                                                  Key = gstatus.StatusID,
                                                  Value = gstatus.StatusDesc,
                                              }).ToDictionary(o => o.Key, o => o.Value);
            return CustomerGroupsData;
        }
        public ErrorBInfo CreateCustomerPayment(CustomerPaymentsBData CustomerPaymentsData, ref int LineNo)
        {
            ErrorBInfo Error = new ErrorBInfo();
            int MaxLineNo = 0;
            try
            {
                if (_context.tblPayments.Any(Pay => Pay.CustomerID == CustomerPaymentsData.CustomerID))
                    MaxLineNo = _context.tblPayments.Where(Pay => Pay.CustomerID == CustomerPaymentsData.CustomerID).Max(Pay => Pay.LineNo);

                tblPayment NewCustomerPayment = new tblPayment()
                {
                    LineNo = MaxLineNo + 1,
                    CustomerID = CustomerPaymentsData.CustomerID,
                    PayTypeID = CustomerPaymentsData.PayTypeID,
                    PaymentDate = CustomerPaymentsData.PaymentDate,
                    RefundF = CustomerPaymentsData.RefundF,
                    Description = CustomerPaymentsData.Description,

                };

                _context.tblPayments.Add(NewCustomerPayment);
                _context.SaveChanges();
                LineNo = MaxLineNo + 1;
            }
            catch (Exception ex)
            {
                Error.errorCode = 100;
                Error.Message = ex.Message;
                logger.Error(ex.ToMessageAndCompleteStacktrace());
            }
            return Error;
        }
        public ErrorBInfo CreateCustomerPaymentGroup(CustomerPaymentGroupsBData CustomerPaymentGroupData)
        {
            ErrorBInfo Error = new ErrorBInfo();
            using (var transaction = _context.Database.BeginTransaction())
            {
                try
                {
                    if (_context.tblDeposits.Any(Dep => Dep.CustomerID == CustomerPaymentGroupData.CustomerID && CustomerPaymentGroupData.LineNo == Dep.LineNo && CustomerPaymentGroupData.AddGroupID == Dep.GroupID))
                    {
                        Error.Message = "Can`t duplicate Group";
                        return Error;
                    }
                    tblDeposit NewCustomerDeposit = new tblDeposit()
                    {
                        LineNo = CustomerPaymentGroupData.LineNo,
                        CustomerID = CustomerPaymentGroupData.CustomerID,
                        GroupID = CustomerPaymentGroupData.AddGroupID,
                        Refunded = 0,
                        Received = CustomerPaymentGroupData.Received,
                        GuideID = 0,
                        VendorID = 0,
                        FitID = 0,
                        DepositTypeID = 1,
                        PaymentDate = DateTime.Now,
                    };

                    _context.tblDeposits.Add(NewCustomerDeposit);
                    _context.SaveChanges();
                    var SaveEntityCustomerPayment = _context.tblPayments.Where(Pay => CustomerPaymentGroupData.CustomerID == Pay.CustomerID
                                                                                            && CustomerPaymentGroupData.LineNo == Pay.LineNo).SingleOrDefault();
                    var AddCredit = _context.tblDeposits.Where(Dep => CustomerPaymentGroupData.CustomerID == Dep.CustomerID
                                                                                            && CustomerPaymentGroupData.LineNo == Dep.LineNo).ToList();
                    SaveEntityCustomerPayment.Credit = AddCredit.Select(DepCredit => DepCredit.Received).Sum();
                    _context.SaveChanges();
                    transaction.Commit();
                }
                catch (Exception ex)
                {
                    Error.errorCode = 100;
                    Error.Message = ex.Message;
                    logger.Error(ex.ToMessageAndCompleteStacktrace());
                    transaction.Rollback();
                }
            }
            return Error;
        }
        public ErrorBInfo SaveCustomerPaymentsData(CustomerPaymentsBData PaymentsData)
        {
            ErrorBInfo Error = new ErrorBInfo();

            try
            {
                List<int> LineNoList = PaymentsData.Rows.Select(Pay => Pay.LineNo).ToList();
                var SaveEntityCustomerPayments = _context.tblPayments.Where(Pay => Pay.CustomerID == PaymentsData.CustomerID
                                                                                         && LineNoList.Contains(Pay.LineNo)).ToList();
                foreach (var PayDate in SaveEntityCustomerPayments)
                {
                    var SaveData = PaymentsData.Rows.Where(data => data.LineNo == PayDate.LineNo).SingleOrDefault();
                    if (SaveData != null)
                    {
                        PayDate.PayTypeID = SaveData.PayTypeID;
                        PayDate.PaymentDate = SaveData.PaymentDate;
                        PayDate.RefundF = SaveData.RefundF;
                        PayDate.Description = SaveData.Description;
                    }
                }
                _context.SaveChanges();
            }
            catch (Exception ex)
            {
                Error.errorCode = 100;
                Error.Message = ex.Message;
                logger.Error(ex.ToMessageAndCompleteStacktrace());
            }

            return Error;
        }
        public ErrorBInfo SaveCustomersGridData(ManageCustomersGridBData Data)
        {
            ErrorBInfo Error = new ErrorBInfo();
            try
            {
                List<int> CustomerIDs = Data.Rows.Select(Customer => Customer.CustomerID).ToList();
                var SaveEntityCustomers = _context.tblCustomers.Where(Customer => CustomerIDs.Contains(Customer.CustomerID)).ToList();
                foreach (var Customer in SaveEntityCustomers)
                {
                    var SaveData = Data.Rows.Where(data => data.CustomerID == Customer.CustomerID).SingleOrDefault();
                    if (SaveData != null)
                    {
                        Customer.Active = SaveData.Active;
                    }
                }
                _context.SaveChanges();
            }
            catch (Exception ex)
            {
                Error.Message = ex.Message;
                logger.Error(ex.ToMessageAndCompleteStacktrace());
            }
            return Error;
        }
        public ErrorBInfo SaveCustomerPaymentGroupsData(CustomerPaymentGroupsBData PaymentGroupsData)
        {
            ErrorBInfo Error = new ErrorBInfo();
            using (var transaction = _context.Database.BeginTransaction())
            {
                try
                {
                    List<int> GroupIDList = PaymentGroupsData.Rows.Select(Group => Group.OldSelectedGroupsID).ToList();
                    var SaveEntityCustomerPaymentGroups = _context.tblDeposits.Where(Pay => Pay.CustomerID == PaymentGroupsData.CustomerID
                                                                                             && PaymentGroupsData.LineNo == Pay.LineNo).ToList();
                    _context.tblDeposits.RemoveRange(SaveEntityCustomerPaymentGroups);
                    _context.SaveChanges();
                    foreach (var PayGRDate in SaveEntityCustomerPaymentGroups)
                    {
                        var SaveData = PaymentGroupsData.Rows.Where(data => data.OldSelectedGroupsID == PayGRDate.GroupID).SingleOrDefault();
                        if (SaveData != null)
                        {
                            PayGRDate.Received = SaveData.Received;
                            PayGRDate.GroupID = SaveData.SelectedGroupsID;
                        }
                    }
                    _context.tblDeposits.AddRange(SaveEntityCustomerPaymentGroups);
                    var SaveEntityCustomerPayment = _context.tblPayments.Where(Pay => PaymentGroupsData.CustomerID==Pay.CustomerID
                                                                                             && PaymentGroupsData.LineNo == Pay.LineNo).SingleOrDefault();
                    SaveEntityCustomerPayment.Credit=PaymentGroupsData.Rows.Select(PayGr=>PayGr.Received).Sum();
                    _context.SaveChanges();
                    transaction.Commit();
                }
                catch (Exception ex)
                {
                    Error.errorCode = 100;
                    Error.Message = ex.Message;
                    logger.Error(ex.ToMessageAndCompleteStacktrace());
                    transaction.Rollback();
                }
            }
            return Error;
        }
        public ErrorBInfo SaveCustomerDetailsData(CustomerDetailsBData Data)
        {
            ErrorBInfo Error = new ErrorBInfo();
            using (var transaction = _context.Database.BeginTransaction())
            {
                try
                {
                    var EditCustomer = (from Customer in _context.tblCustomers where Customer.CustomerID == Data.CustomerID select Customer).SingleOrDefault();
                    if (EditCustomer != null)
                    {
                        EditCustomer.CustomerCode = Data.CustomerCode;
                        EditCustomer.OrganizationName = Data.OrganizationName;
                        EditCustomer.Address = Data.Address;
                        EditCustomer.Address2 = Data.Address2;
                        EditCustomer.City = Data.CityID == -1 ? Data.SelectedCity : (from city in _context.tblCities where city.CityID == Data.CityID select city.City).SingleOrDefault();
                        EditCustomer.CityID = Data.CityID != -1 ? Data.CityID : null;
                        EditCustomer.StateID = Data.SelectedStateID;
                        EditCustomer.CountryID = Data.SelectedCountryID;
                        EditCustomer.PostalCode = Data.PostalCode;
                        EditCustomer.CCEMail = Data.CCEMail;
                        EditCustomer.PhoneNumber1 = Data.PhoneNumber1;
                        EditCustomer.PhoneNumber2 = Data.PhoneNumber2;
                        EditCustomer.FaxNumber = Data.FaxNumber;
                        EditCustomer.Note = Data.Note;
                        EditCustomer.Mail = Data.Mail;
                        EditCustomer.Active = Data.Active;

                        var SaveEntityContactDetails = _context.tblCustomerContacts.Where(cntdet => cntdet.CustomerID == Data.CustomerID).ToList();
                        foreach (var CntDet in SaveEntityContactDetails)
                        {
                            var SaveData = Data.ContactRows.Where(data => data.CCID == CntDet.CCID).SingleOrDefault();
                            if (SaveData != null)
                            {
                                CntDet.Name = SaveData.Name;
                                CntDet.Title = SaveData.Title;
                                CntDet.EMail = SaveData.EMail;
                                CntDet.Phone = SaveData.Phone;
                                CntDet.Fax = SaveData.Fax;
                            }
                        }
                        _context.SaveChanges();
                        transaction.Commit();
                    }
                    else
                    {
                        Error.errorCode = 130;
                        Error.Message = "Customer Can`t be found:";
                        transaction.Rollback();
                    }
                }
                catch (Exception ex)
                {
                    Error.errorCode = 100;
                    Error.Message = ex.Message;
                    logger.Error(ex.ToMessageAndCompleteStacktrace());
                    transaction.Rollback();
                }
            }
            return Error;
        }
        public ErrorBInfo CreateCustomerContact(CustomerDetailsBData CustomerContactData)
        {
            ErrorBInfo Error = new ErrorBInfo();
            try
            {
                tblCustomerContact NewCustomerContact = new tblCustomerContact()
                {
                    CustomerID = CustomerContactData.CustomerID,
                    Name = CustomerContactData.Name,
                    Title = CustomerContactData.Title,
                    EMail = CustomerContactData.EMail,
                    Phone = CustomerContactData.Phone,
                    Fax = CustomerContactData.Fax,
                };
                _context.tblCustomerContacts.Add(NewCustomerContact);
                _context.SaveChanges();
            }
            catch (Exception ex)
            {
                Error.errorCode = 100;
                Error.Message = ex.Message;
                logger.Error(ex.ToMessageAndCompleteStacktrace());
            }
            return Error;
        }
        public Dictionary<string, string> LoadState()
        {
            Dictionary<string, string> States = new Dictionary<string, string>();
            States = (from state in _context.tblStates where state.Active == true orderby state.StateID select new { Key = state.StateID, Value = state.StateID }).ToDictionary(o => o.Key, o => o.Value);
            if (States == null)
            {
                States = new Dictionary<string, string>();
            }
            return States;
        }
        public Dictionary<int, string> LoadCity(int CountryID, string StateID)
        {
            Dictionary<int, string> City = new Dictionary<int, string>();
            if (CountryID != 0)
            {
                City = (from city in _context.tblCities where city.CountryID == CountryID && city.Active == true orderby city.City select new { Key = city.CityID, Value = city.City }).ToDictionary(o => o.Key, o => o.Value);
            }
            else
            {
                City = (from city in _context.tblCities where city.StateID == StateID && city.Active == true orderby city.City select new { Key = city.CityID, Value = city.City }).ToDictionary(o => o.Key, o => o.Value);
            }
            if (City == null)
                City = new Dictionary<int, string>();
            return City;
        }
        public void Dispose()
        {
            _context.Dispose();
        }
    }
}
